<template>
    <div class="draw-tools">
        <ul>
            <li
                v-for="item in drawTypes"
                :key="item.type"
                @click="item.function(item.type)"
                :class="currentDrawType === item.type ? 'active' : ''"
            >
                {{ item.name }}
            </li>
            <li v-if="props.isClear" @click="clear">清空</li>
        </ul>
    </div>
</template>

<script setup>
import util from '../utils'
import { useMapStore } from '../store'
import { ref, onMounted, reactive, computed, onUnmounted } from 'vue'
import { message } from 'ant-design-vue'
const mapStore = useMapStore()
const map = ref(null)
const props = defineProps({
    isMessage: {
        default: false,
    }, //是否提示
    isClear: {
        default: true,
    }, //是否显示清空按钮
    types: {
        default: ['points', 'polylines', 'polygons'],
    }, //工具类型
    polylinesStyle: {
        default: {},
    },
    polygonsStyle: {
        default: {},
    },
})
onMounted(() => {
    map.value = mapStore.map
})
const currentDrawType = ref(null)
const changeDrawType = type => {
    if (currentDrawType.value === type) {
        currentDrawType.value = null
        drawOff()
        props.isMessage && message.info('结束')
    } else {
        currentDrawType.value = type
        drawOn()
        if (type === 'points') {
            props.isMessage && message.info('标点')
            drawPoint()
        }
        if (type === 'polylines') {
            props.isMessage && message.info('线')
            drawLine()
        }
        if (type === 'polygons') {
            props.isMessage && message.info('多边形')
            drawGon()
        }
    }
}
const drawToolsList = {
    points: {
        name: '点',
        type: 'points',
        function: changeDrawType,
    },
    polylines: {
        name: '线',
        type: 'polylines',
        function: changeDrawType,
    },
    polygons: {
        name: '面',
        type: 'polygons',
        function: changeDrawType,
    },
}
const drawTypes = computed(() => {
    const tempArray = []
    props.types.forEach(item => {
        const temp = drawToolsList[item]
        temp && tempArray.push(temp)
    })
    return tempArray
})
const tempLayers = reactive({
    lineNode: [],
    lineNodeLen: 0,
    tempLine: null,
    tempNode: [],
    gonNode: [],
    gonNodeLen: 0,
    tempGon: null,
})
const overLayers = reactive({
    polylines: [],
    polygons: [],
    points: [],
})
const clearTemps = () => {
    tempLayers.lineNode = []
    tempLayers.lineNodeLen = 0
    tempLayers.tempLine && tempLayers.tempLine.remove()
    tempLayers.tempNode.map(node => node.remove())
    tempLayers.gonNode = []
    tempLayers.gonNodeLen = 0
    tempLayers.tempGon && tempLayers.tempGon.remove()
}
const drawOn = () => {
    clearTemps()
    map.value.off('click')
    map.value.off('dblclick')
    map.value.off('mousemove')
    map.value.doubleClickZoom.disable()
}
const drawOff = () => {
    clearTemps()
    map.value.off('click')
    map.value.off('dblclick')
    map.value.off('mousemove')
    map.value.doubleClickZoom.enabled()
}
const drawPoint = () => {
    map.value.on('click', evt => {
        overLayers.points.push(util.map.createMakerByLatlng(map.value, evt.latlng, {}))
    })
}
const tempStyleOptions = {
    color: 'rgba(255,0,0,0.85)',
    weight: 3,
    opacity: 0.85,
    showMeasurements: true,
    measurementOptions: { minDistance: 500 },
}
const finalStyleOptions = {
    color: 'rgba(0,255,0,0.85)',
    weight: 3,
    opacity: 0.85,
    showMeasurements: true,
    measurementOptions: { minDistance: 500 },
}
const drawLine = () => {
    map.value.on('click', evt => {
        tempLayers.lineNode.push([evt.latlng.lat, evt.latlng.lng])
        tempLayers.tempNode.push(addNode(evt.latlng, map.value))
        tempLayers.lineNodeLen = tempLayers.lineNode.length
    })
    map.value.on('mousemove', evt => {
        if (tempLayers.lineNodeLen >= 1) {
            tempLayers.tempLine && tempLayers.tempLine.remove()
            tempLayers.lineNode[tempLayers.lineNodeLen] = [evt.latlng.lat, evt.latlng.lng]
            tempLayers.tempLine = util.map.createPolyline(
                map.value,
                tempLayers.lineNode,
                tempStyleOptions
            )
        }
    })
    map.value.on('dblclick', () => {
        overLayers.polylines.push(
            util.map.createPolyline(map.value, tempLayers.lineNode, finalStyleOptions)
        )
        clearTemps()
    })
}
const drawGon = () => {
    map.value.on('click', evt => {
        tempLayers.gonNode.push([evt.latlng.lat, evt.latlng.lng])
        tempLayers.tempNode.push(addNode(evt.latlng, map.value))
        tempLayers.gonNodeLen = tempLayers.gonNode.length
    })
    map.value.on('mousemove', evt => {
        tempLayers.tempGon && tempLayers.tempGon.remove()
        if (tempLayers.gonNodeLen === 1) {
            tempLayers.gonNode[tempLayers.gonNodeLen] = [evt.latlng.lat, evt.latlng.lng]
            tempLayers.tempGon = util.map.createPolyline(
                map.value,
                tempLayers.gonNode,
                tempStyleOptions
            )
        } else if (tempLayers.gonNodeLen >= 2) {
            tempLayers.gonNode[tempLayers.gonNodeLen] = [evt.latlng.lat, evt.latlng.lng]
            tempLayers.tempGon = util.map.createPolygon(
                map.value,
                tempLayers.gonNode,
                tempStyleOptions
            )
        }
    })
    map.value.on('dblclick', () => {
        overLayers.polygons.push(
            util.map.createPolygon(map.value, tempLayers.gonNode, finalStyleOptions)
        )
        clearTemps()
    })
}
const addNode = (latlng, map) => {
    let icon = util.map.createIcon({
        iconUrl: util.getImgUrl('./../assets/images/node2.png'),
        iconSize: [10, 10],
    })
    return util.map.createMakerByLatlng(map, latlng, {
        icon,
    })
}
const clear = () => {
    if (currentDrawType.value) {
        overLayers[currentDrawType.value].forEach(item => item.remove())
    } else {
        Object.keys(overLayers).forEach(key => {
            overLayers[key].forEach(item => item.remove())
        })
    }
}
onUnmounted(() => {})
</script>

<style scoped lang="less">
.draw-tools {
    position: absolute;
    right: 15px;
    top: 15px;
    z-index: 999;
    height: 36px;
    box-shadow: 0 0 50px 2px rgba(0, 0, 0, 0.35);
    background-color: #fff;

    ul {
        display: flex;
        padding: 0;
        margin: 0;
        list-style: none;

        li {
            min-width: 80px;
            padding: 0 15px;
            height: 36px;
            font-size: 13px;
            line-height: 36px;
            cursor: pointer;
        }

        li.active {
            background-color: rgb(102, 156, 255);
            color: #fff;
        }

        li:hover {
            background-color: rgb(212, 224, 246);
        }
    }
}
</style>
